package com.ybear.ybnetworkutil.request;

import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.ybear.ybnetworkutil.http.BodyType;
import com.ybear.ybnetworkutil.call.CallDownloadListener;
import com.ybear.ybnetworkutil.call.Callback;
import com.ybear.ybnetworkutil.call.CallbackString;

import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 请求类
 */
public abstract class Request implements IRequest {
    private long id = -1L;
    private final Param param = new Param();
    private String method = Method.GET;    //用于标识当前的请求方式
    @Nullable
    private Callback callback;
    @Nullable
    private CallbackString callbackString;
    private CallDownloadListener callDownloadListener;
    private BodyType bodyType;
    private int maxReCount = 5;
    private final AtomicInteger currentReCount = new AtomicInteger( 0 );

    protected Request() {
    }

    @NonNull
    @Override
    public String toString() {
        return "Request{" +
                "url=" + toUrl() +
                "fullUrl=" + toFullUrl() +
                ", id=" + id +
                ", param=" + param +
                ", method=" + method +
                ", callback=" + callback +
                ", callbackString=" + callbackString +
                ", callDownloadListener=" + callDownloadListener +
                ", maxReCount=" + maxReCount +
                ", currentReCount=" + currentReCount.get() +
                '}';
    }

    @NonNull
    public String toParams() { return param.toParamString(); }

    @NonNull
    public String toParamsOfJson() { return param.toParamJson(); }

    @NonNull
    public String toParamBodyString() { return param.toParamBodyString(); }

    @NonNull
    public String toUrl() {
        String url = !TextUtils.isEmpty( url = this.url() ) ? url : "/";
        String api = !TextUtils.isEmpty( api = this.api() ) ? api : "";
        boolean eq = url.endsWith( "/" );
        return (!eq && !"".equals(api) ? url + "/" : url) + api;
    }

    @NonNull
    public String toFullUrl() {
        String url = this.toUrl();
        String paramStr = this.toParams();
        return TextUtils.isEmpty(paramStr) ? url : url + "?" + paramStr;
    }

    public long getId() { return id; }
    public Request setId(long id) {
        this.id = id;
        return this;
    }

    @NonNull
    public Request addParam(@NonNull String key, @Nullable Object val) {
        param.addParam( key, val );
        return this;
    }

    public Request addParam(@NonNull String key, @Nullable String val) {
        param.addParam( key, val );
        return this;
    }

    @NonNull
    public String setParam(@Nullable String raw) {
        Object ret = param.setParam( raw );
        return ret != null ? ret.toString() : "";
    }

    @NonNull
    public <P extends Param> Request addParamAll(P param) {
        TreeMap<String, Object> map = null;
        //传入的Param不能为空以及存在数据，否则反射里边的变量
        if( param != null && ( map = param.getMap() ).size() == 0 ) map = param.toMap();
        if( map != null && map.size() > 0 ) this.param.addParamAll( map );
        return this;
    }

    public @NonNull Param getParam() { return param; }

    public Request clearParam() {
        param.getMap().clear();
        return this;
    }

    public String getMethod() { return method; }
    public Request setMethod(@Nullable String method) {
        this.method = method;
        return this;
    }

    @Nullable
    public Callback getCallback() { return callback; }
    public Request setCallback(@Nullable Callback callback) {
        this.callback = callback;
        return this;
    }

    @Nullable
    public CallbackString getCallbackString() { return callbackString; }
    public Request setCallbackString(@Nullable CallbackString callback) {
        callbackString = callback;
        return this;
    }

    @Nullable
    public CallDownloadListener getCallDownloadListener() { return callDownloadListener; }
    public Request setCallDownloadListener(@Nullable CallDownloadListener l) {
        callDownloadListener = l;
        return this;
    }

    public BodyType getBodyType() { return bodyType; }
    public void setBodyType(BodyType bodyType) { this.bodyType = bodyType; }

    /**
     * 自增当前数量
     * @return  this
     */
    public int incrementCurrentReCount() { return currentReCount.incrementAndGet(); }
    public int decrementCurrentReCount() { return currentReCount.decrementAndGet(); }
    public int getCurrentReCount() { return currentReCount.get(); }
    public Request setCurrentReCount(int currentCount) {
        this.currentReCount.set( currentCount );
        return this;
    }

    public int getMaxReCount() { return maxReCount; }
    public Request setMaxReCount(int maxReCount) {
        this.maxReCount = maxReCount;
        return this;
    }
}
